package com.ouc.common.utils;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 时间工具类
 *
 * @author ouc
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
  public static String YYYY = "yyyy";

  public static String YYYY_MM = "yyyy-MM";

  public static String YYYY_MM_DD = "yyyy-MM-dd";

  public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

  public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

  private static String[] parsePatterns = {
      "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
      "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
      "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

  /**
   * 获取当前Date型日期
   *
   * @return Date() 当前日期
   */
  public static Date getNowDate() {
    return new Date();
  }

  /**
   * 获取当前日期, 默认格式为yyyy-MM-dd
   *
   * @return String
   */
  public static String getDate() {
    return dateTimeNow(YYYY_MM_DD);
  }

  public static final String getTime() {
    return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
  }

  public static final String dateTimeNow() {
    return dateTimeNow(YYYYMMDDHHMMSS);
  }

  public static final String dateTimeNow(final String format) {
    return parseDateToStr(format, new Date());
  }

  public static final String dateTime(final Date date) {
    return parseDateToStr(YYYY_MM_DD, date);
  }

  public static final String parseDateToStr(final String format, final Date date) {
    return new SimpleDateFormat(format).format(date);
  }

  public static final Date dateTime(final String format, final String ts) {
    try {
      return new SimpleDateFormat(format).parse(ts);
    } catch (ParseException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * 日期路径 即年/月/日 如2018/08/08
   */
  public static final String datePath() {
    Date now = new Date();
    return DateFormatUtils.format(now, "yyyy/MM/dd");
  }

  /**
   * 日期路径 即年/月/日 如20180808
   */
  public static final String dateTime() {
    Date now = new Date();
    return DateFormatUtils.format(now, "yyyyMMdd");
  }

  /**
   * 日期型字符串转化为日期 格式
   */
  public static Date parseDate(Object str) {
    if (str == null) {
      return null;
    }
    try {
      return parseDate(str.toString(), parsePatterns);
    } catch (ParseException e) {
      return null;
    }
  }

  /**
   * 获取服务器启动时间
   */
  public static Date getServerStartDate() {
    long time = ManagementFactory.getRuntimeMXBean().getStartTime();
    return new Date(time);
  }

  /**
   * 计算相差天数
   */
  public static int differentDaysByMillisecond(Date date1, Date date2) {
    return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
  }


  /**
   * 计算相差秒数
   *
   * @param date1 开始时间
   * @param date2 结束时间
   * @return
   */
  public static long differentSecondByMillisecond(Date date1, Date date2) {
    long time = date2.getTime();
    long time1 = date1.getTime();
    String s = DateUtils.parseDateToStr("yyyy-MM-dd", date1);
    long l = (time1 - time) / 1000;
    /*return Math.abs((int) ((date2.getTime() - date1.getTime()) / 1000))*/
    return Math.abs(((date2.getTime() - date1.getTime()) / 1000));
  }


  /**
   * 计算两个时间差
   */
  public static String getDatePoor(Date endDate, Date nowDate) {
    long nd = 1000 * 24 * 60 * 60;
    long nh = 1000 * 60 * 60;
    long nm = 1000 * 60;
    // long ns = 1000;
    // 获得两个时间的毫秒时间差异
    long diff = endDate.getTime() - nowDate.getTime();
    // 计算差多少天
    long day = diff / nd;
    // 计算差多少小时
    long hour = diff % nd / nh;
    // 计算差多少分钟
    long min = diff % nd % nh / nm;
    // 计算差多少秒//输出结果
    // long sec = diff % nd % nh % nm / ns;
    return day + "天" + hour + "小时" + min + "分钟";
  }

  /**
   * 计算时间差
   *
   * @param endDate   最后时间
   * @param startTime 开始时间
   * @return 时间差（天/小时/分钟）
   */

  public static String timeDistance(Date endDate, Date startTime) {
    long nd = 1000 * 24 * 60 * 60;
    long nh = 1000 * 60 * 60;
    long nm = 1000 * 60;
    // long ns = 1000;
    // 获得两个时间的毫秒时间差异
    long diff = endDate.getTime() - startTime.getTime();
    // 计算差多少天
    long day = diff / nd;
    // 计算差多少小时
    long hour = diff % nd / nh;
    // 计算差多少分钟
    long min = diff % nd % nh / nm;
    // 计算差多少秒//输出结果
    // long sec = diff % nd % nh % nm / ns;
    return day + "天" + hour + "小时" + min + "分钟";
  }


  /**
   * 增加 LocalDateTime ==> Date
   */
  public static Date toDate(LocalDateTime temporalAccessor) {
    ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
    return Date.from(zdt.toInstant());
  }

  /**
   * 增加 LocalDate ==> Date
   */
  public static Date toDate(LocalDate temporalAccessor) {
    LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
    ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
    return Date.from(zdt.toInstant());
  }

  /**
   * 从原始时间通过和小时数
   * 得到新时间
   *
   * @param originDate 原始时间
   * @param hours      差距小时数
   * @return
   */
  public static Date getTimeFormDifference(Date originDate, Integer hours) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(originDate);
    cal.add(Calendar.HOUR, hours);
    return cal.getTime();

  }

  /**
   * 判断所给时间是否在指定时间范围内
   *
   * @param testDate  测试时间
   * @param startDate 开始时间
   * @param endDate   结束时间
   * @return
   */
  public static boolean betweenDate(Date testDate, Date startDate, Date endDate) {
    if (testDate.getTime() == startDate.getTime()
        || testDate.getTime() == endDate.getTime()) {
      return true;
    }

    Calendar date = Calendar.getInstance();
    date.setTime(testDate);

    Calendar begin = Calendar.getInstance();
    begin.setTime(startDate);

    Calendar end = Calendar.getInstance();
    end.setTime(endDate);

    return date.after(begin) && date.before(end);

  }

  /**
   * 计算两个时间点之间的时间
   * 如果默认则每个时间之间差一小时
   *
   * @param startDate 开始时间
   * @param endDate   结束时间
   * @param type      时间点间距类型有hour，day，year，minute四种类型之后可以加
   * @return 时间点组成的集合
   */
  public static List<Date> getDateBetweenDate(Date startDate, Date endDate, String type) {
    Calendar calendar = Calendar.getInstance();
    //String startDateStr = DateUtils.parseDateToStr("yyyy-MM-dd HH:MM:SS", startDate);
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    List<Date> dateList = new ArrayList<>();

    while (startDate.getTime() < endDate.getTime()) {
      dateList.add(parseDate(simpleDateFormat.format(startDate)));
      calendar.setTime(startDate);
      switch (type) {
        case "day":
          calendar.add(Calendar.DATE, 1);
          break;
        case "year":
          calendar.add(Calendar.YEAR, 1);
          break;
        case "minute":
          calendar.add(Calendar.MINUTE, 1);
          break;
        default:
          calendar.add(Calendar.HOUR, 1);
          break;
      }

      startDate = calendar.getTime();
    }
    return dateList;
  }

  /**
   * 计算两个时间的差值
   *
   * @param dateStart 开始时间
   * @param dateStop  结束时间
   * @return 时间以天作为单位
   */
  public static Integer dateDifferent(String dateStart, String dateStop) {
//        String dateStart = "2022-04-01 12:20:43";
//        String dateStop = "2022-04-08 15:57:48";
    long diff, diffSeconds, diffMinutes, diffHours, diffDays = 0;
    SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
    try {
      Date d1 = format.parse(dateStart);//毫秒ms
      Date d2 = format.parse(dateStop);//毫秒ms
      diff = d2.getTime() - d1.getTime();
     /* diffSeconds = diff / 1000 % 60;
      diffMinutes = diff / (60 * 1000) % 60;
      diffHours = diff / (60 * 60 * 1000) % 24;*/
      diffDays = diff / (24 * 60 * 60 * 1000);
      /*System.out.print("两个时间相差:");
      System.out.print(diffDays + "天,");*/
    } catch (ParseException e) {
      e.printStackTrace();
    }
    int days = (int) diffDays;
    return days;
  }


}


